package com.lykj.lib_base.net.http

import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import com.lykj.lib_base.app.BaseApplication
import com.lykj.lib_base.internal.utils.CookieUtils
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import java.util.concurrent.TimeUnit


/**
 * ================================================
 * OkHttp管理类(提供初始化默认OkHttp)
 * ================================================
 *
 * @author gosha
 * @date 2022/9/2-16:26
 */
object OkHttpManager {
    private var okHttpClient: OkHttpClient? = null

    open fun getDefaultOkHttpClient(): OkHttpClient {
        if (null == okHttpClient) {
            okHttpClient = getNewOKHttpClient()
        }
        return okHttpClient!!
    }

    open fun getNewOKHttpClient(): OkHttpClient {
        //定制OkHttp
        //设置成单例
        val builder = OkHttpClient.Builder()
//            .pingInterval(10, TimeUnit.SECONDS)
        builder.connectTimeout(30, TimeUnit.SECONDS)
        builder.readTimeout(25, TimeUnit.SECONDS)
        builder.writeTimeout(25, TimeUnit.SECONDS)
        builder.addInterceptor(RequestHeaderInterceptor())
        builder.addInterceptor(ResponseCookieInterceptor())
        builder.addInterceptor(RequestAddCookieInterceptor())

        //打包时修改
//        if (AppUtils.isAppDebug()) {
//            //新建log拦截器
//            val loggingInterceptor = HttpLoggingInterceptor()
//            //日志显示级别
//            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
//
//            /*链接超时*/
//            builder.connectTimeout(15, TimeUnit.SECONDS)
//            /*数据读取*/
//            builder.readTimeout(15, TimeUnit.SECONDS)
//            /*数据写入*/
//            builder.writeTimeout(15, TimeUnit.SECONDS)
//            //OkHttp进行添加拦截器loggingInterceptor
//            builder.addInterceptor(loggingInterceptor)
//        }

        return builder.build()
    }

    /**
     * 请求头拦截器
     */
    class RequestHeaderInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val oldRequest: Request = chain.request() // 获取旧连接

            val requestBuilder: Request.Builder = oldRequest.newBuilder() // 建立新的构建者

            // 将旧请求的请求方法和请求体设置到新请求中
            requestBuilder.method(oldRequest.method, oldRequest.body)
            // 获取旧请求的头
            val headers: Headers = oldRequest.headers
            if (headers != null) {
                val names: Set<String> = headers.names()
                for (name in names) {
                    val value: String? = headers[name]
                    // 将旧请求的头设置到新请求中
                    value?.let { requestBuilder.header(name, it) }
                }
            }

//            if (BaseApplication.instance?.getUserInfo() != null
//                && !BaseApplication.instance?.getUserInfo()?.token.isNullOrBlank()
//            ) {
//                // 添加额外的自定义公共请求头
//                requestBuilder.header(
//                    "Authorization",
//                    "Bearer ${BaseApplication.instance?.getUserInfo()?.token}"
//                )
//            }

            // 建立新请求连接
            val newRequest: Request = requestBuilder.build()
            return chain.proceed(newRequest)
        }
    }


    /**
     * 拦截响应获取指定内容(Cookie)
     */
    class ResponseCookieInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            // 获取 Cookie
            val resp = chain.proceed(chain.request())
            val cookies = resp.headers("Set-Cookie")
            val cookieStr = StringBuilder()
            if (cookies != null && cookies.isNotEmpty()) {
                for (i in cookies.indices) {
                    if (cookies[i].length < 240) {
                        continue
                    }
                    cookieStr.append(cookies[i])
                }

//                if (AppUtils.isAppDebug()) {
//                    LogUtils.e("获取 Cookie: $cookieStr")
//                }

                var isAgent = false
                try {
                    isAgent = resp.request.headers["isAgent"].equals("1")
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                var token = ""

                if (isAgent) {
                    cookieStr.split(";").forEach {
                        if (it.contains("box66_daili_user_token")) {
                            token = it.replace("box66_daili_user_token=", "")
                        }
                    }
                } else {
                    cookieStr.split(";").forEach {
                        if (it.contains("box66_h5_user_token")) {
                            token = it.replace("box66_h5_user_token=", "")
                        }
                    }
                }

//                if (AppUtils.isAppDebug()) {
//                    LogUtils.e("h5_user_token:$token")
//                }

                if (isAgent) {
                    CookieUtils.saveAgentToken(token)
                } else {
                    CookieUtils.saveToken(token)
                }
            }
            return resp
        }
    }

    /**
     * 拦截请求加入头指定内容(Cookie)
     */
    class RequestAddCookieInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            //设置 Cookie
            //FIXME:手动设置cookie,测试用

            var cookieStr = ""
            val request = chain.request()
            var isAgent = false
            try {
                isAgent = request.headers["isAgent"].equals("1")
            } catch (e: Exception) {
                e.printStackTrace()
            }

            cookieStr = if (isAgent) {
                "box66_daili_user_token=" + CookieUtils.getAgentCookieToken()
            } else {
                "box66_h5_user_token=" + CookieUtils.getCookieToken()
            }

            return if (cookieStr.isNotEmpty()) {
        //                request.newBuilder().header("Cookie",cookieStr).build()
                chain.proceed(chain.request().newBuilder().header("Cookie", cookieStr).build())
            } else {
                chain.proceed(request)
            }
        }
    }
}